package luke.core.utils;

import luke.audio.metadata.Song;
import luke.audio.metadata.SongMetadataExtractor;

import javax.swing.*;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import luke.core.logging.LogUtil; // 添加LogUtil导入

/**
 * 应用状态管理器
 * 用于统一管理应用状态，支持观察者模式，一处更新多处响应
 */
public class AppStateManager {
    // 单例实例
    private static AppStateManager instance;
    private File bpmFileAcquired;

    public void setBpmFileAcquired(File bpmFileAcquired) {
        this.bpmFileAcquired = bpmFileAcquired;
        //通知BPM文件已获取
        notifyBpmFileAcquired();
    }

    private void notifyBpmFileAcquired() {
        SwingUtilities.invokeLater(() -> {
            for (StateListener listener : stateListeners) {
                listener.onBpmFileAcquired(bpmFileAcquired);
            }
        });
    }

    // 应用状态
    private String audioDirectory = ""; // 音频目录
    private List<File> sharedSelectedFiles = Collections.synchronizedList(new LinkedList<>());  // 已选择的文件列表
    private Map<File, Song> songData; // 歌曲数据缓存

    public String getAudioDirectory() {
        return audioDirectory;
    }

    public void setAudioDirectory(String audioDirectory) {
        this.audioDirectory = audioDirectory;
    }

    private double plannedDuration = 90.0; // 计划生成时长（分钟）
    private boolean keepOriginalSpeed = false; // 是否保持原速
    private boolean truncateExceedingFiles = false; // 是否截断超出时长的文件
    private String searchText = ""; // 搜索文本
    private String analysisProgressMessage = ""; // 分析进度消息
    private int analysisProgress = 0; // 分析进度百分比
    private File analysisCurrentFile = null; // 当前正在分析的文件
    private List<File> allListFiles = new ArrayList<>();

    public List<File> getAllListFiles() {
        return allListFiles;
    }

    public void setAllListFiles(List<File> allListFiles) {
        this.allListFiles.clear();
        this.allListFiles.addAll(allListFiles);
        //通知所有文件列表已经改变
        notifyAllListFilesChange();
    }


    // 观察者列表
    private List<StateListener> stateListeners = new ArrayList<>();

    /**
     * 私有构造函数，防止外部实例化
     */
    private AppStateManager() {
        SongMetadataExtractor songMetadataExtractor = SongMetadataExtractor.getInstance();
        this.songData = songMetadataExtractor.getSongData();
    }

    /**
     * 获取单例实例
     *
     * @return AppStateManager实例
     */
    public static synchronized AppStateManager getInstance() {
        if (instance == null) {
            instance = new AppStateManager();
        }
        return instance;
    }

    /**
     * 添加状态监听器
     *
     * @param listener 状态监听器
     */
    public void addListener(StateListener listener) {
        if (!stateListeners.contains(listener)) {
            stateListeners.add(listener);
        }
    }


    /**
     * 更新已选择的文件列表
     */
    public void updateSelectedFiles() {
        notifySelectedFilesChange();
    }

    /**
     * 获取已选择的文件列表
     *
     * @return 已选择的文件列表
     */
    public List<File> getSharedSelectedFiles() {
        return this.sharedSelectedFiles;
    }

    /**
     * 设置歌曲数据缓存
     *
     * @param songData 歌曲数据缓存
     */
    public void setSongData(Map<File, Song> songData) {
        this.songData = songData != null ? new ConcurrentHashMap<>(songData) : new ConcurrentHashMap<>();
        notifySongDataChange();
    }

    /**
     * 获取歌曲数据缓存
     *
     * @return 歌曲数据缓存
     */
    public Map<File, Song> getSongData() {

        return this.songData;
    }

    /**
     * 设置计划生成时长
     *
     * @param plannedDuration 计划生成时长（分钟）
     */
    public void setPlannedDuration(double plannedDuration) {
        this.plannedDuration = plannedDuration;
        notifyPlannedDurationChange();
    }

    /**
     * 获取计划生成时长
     *
     * @return 计划生成时长（分钟）
     */
    public double getPlannedDuration() {
        return plannedDuration;
    }

    /**
     * 设置是否保持原速
     *
     * @param keepOriginalSpeed 是否保持原速
     */
    public void setKeepOriginalSpeed(boolean keepOriginalSpeed) {
        this.keepOriginalSpeed = keepOriginalSpeed;
        notifyKeepOriginalSpeedChange();
    }

    /**
     * 获取是否保持原速
     *
     * @return 是否保持原速
     */
    public boolean isKeepOriginalSpeed() {
        return keepOriginalSpeed;
    }

    /**
     * 设置是否截断超出时长的文件
     *
     * @param truncateExceedingFiles 是否截断超出时长的文件
     */
    public void setTruncateExceedingFiles(boolean truncateExceedingFiles) {
        LogUtil.debug("AppStateManager", "setTruncateExceedingFiles", "设置截断选项状态: " + truncateExceedingFiles);
        this.truncateExceedingFiles = truncateExceedingFiles;
        notifyTruncateExceedingFilesChange();
    }

    /**
     * 获取是否截断超出时长的文件
     *
     * @return 是否截断超出时长的文件
     */
    public boolean isTruncateExceedingFiles() {
        LogUtil.debug("AppStateManager", "isTruncateExceedingFiles", "获取截断选项状态: " + truncateExceedingFiles);
        return truncateExceedingFiles;
    }

    /**
     * 设置搜索文本
     *
     * @param searchText 搜索文本
     */
    public void setSearchText(String searchText) {
        this.searchText = searchText != null ? searchText : "";
        notifySearchTextChange();
    }

    /**
     * 获取搜索文本
     *
     * @return 搜索文本
     */
    public String getSearchText() {
        return searchText;
    }

    /**
     * 设置分析进度消息
     *
     * @param message 分析进度消息
     */
    public void setAnalysisProgressMessage(String message) {
        this.analysisProgressMessage = message != null ? message : "";
        notifyAnalysisProgressMessageChange();
    }

    /**
     * 获取分析进度消息
     *
     * @return 分析进度消息
     */
    public String getAnalysisProgressMessage() {
        return analysisProgressMessage;
    }

    /**
     * 设置分析进度百分比
     *
     * @param progress 分析进度百分比
     */
    public void setAnalysisProgress(int progress) {
        this.analysisProgress = Math.max(0, Math.min(100, progress));
        notifyAnalysisProgressChange();
    }

    /**
     * 获取分析进度百分比
     *
     * @return 分析进度百分比
     */
    public int getAnalysisProgress() {
        return analysisProgress;
    }

    /**
     * 设置当前正在分析的文件
     *
     * @param file 当前正在分析的文件
     */
    public void setAnalysisCurrentFile(File file) {
        this.analysisCurrentFile = file;
        notifyAnalysisCurrentFileChange();
    }

    /**
     * 获取当前正在分析的文件
     *
     * @return 当前正在分析的文件
     */
    public File getAnalysisCurrentFile() {
        return analysisCurrentFile;
    }

    /**
     * 通知所有监听器已选择文件列表已更新（异步）
     */
    private void notifySelectedFilesChange() {
        SwingUtilities.invokeLater(() -> {
            for (StateListener listener : stateListeners) {
                listener.onSelectedFilesChanged();
            }
        });
    }

    /**
     * 通知所有监听器歌曲数据缓存已更新（异步）
     */
    private void notifySongDataChange() {
        SwingUtilities.invokeLater(() -> {
            for (StateListener listener : stateListeners) {
                listener.onSongDataChanged();
            }
        });
    }

    /**
     * 通知所有监听器计划生成时长已更新（异步）
     */
    private void notifyPlannedDurationChange() {
        SwingUtilities.invokeLater(() -> {
            for (StateListener listener : stateListeners) {
                listener.onPlannedDurationChanged(plannedDuration);
            }
        });
    }

    /**
     * 通知所有监听器是否保持原速已更新（异步）
     */
    private void notifyKeepOriginalSpeedChange() {
        SwingUtilities.invokeLater(() -> {
            for (StateListener listener : stateListeners) {
                listener.onKeepOriginalSpeedChanged(keepOriginalSpeed);
            }
        });
    }

    /**
     * 通知所有监听器是否截断超出时长的文件已更新（异步）
     */
    private void notifyTruncateExceedingFilesChange() {
        SwingUtilities.invokeLater(() -> {
            for (StateListener listener : stateListeners) {
                listener.onTruncateExceedingFilesChanged(truncateExceedingFiles);
            }
        });
    }

    /**
     * 通知所有监听器搜索文本已更新（异步）
     */
    private void notifySearchTextChange() {
        SwingUtilities.invokeLater(() -> {
            for (StateListener listener : stateListeners) {
                listener.onSearchTextChanged(searchText);
            }
        });
    }

    /**
     * 通知所有监听器分析进度消息已更新（异步）
     */
    private void notifyAnalysisProgressMessageChange() {
        SwingUtilities.invokeLater(() -> {
            for (StateListener listener : stateListeners) {
                listener.onAnalysisProgressMessageChanged(analysisProgressMessage);
            }
        });
    }

    /**
     * 通知所有监听器分析进度百分比已更新（异步）
     */
    private void notifyAnalysisProgressChange() {
        SwingUtilities.invokeLater(() -> {
            for (StateListener listener : stateListeners) {
                listener.onAnalysisProgressChanged(analysisProgress);
            }
        });
    }

    /**
     * 通知所有监听器当前正在分析的文件已更新（异步）
     */
    private void notifyAnalysisCurrentFileChange() {
        SwingUtilities.invokeLater(() -> {
            for (StateListener listener : stateListeners) {
                listener.onAnalysisCurrentFileChanged(analysisCurrentFile);
            }
        });
    }

    /**
     * 通知所有监听器所有文件列表已更新（异步）
     */
    private void notifyAllListFilesChange() {
        SwingUtilities.invokeLater(() -> {
            for (StateListener listener : stateListeners) {
                listener.onAllListFilesChanged();
            }
        });
    }

    public void setSharedSelectedFiles(List<File> sharedSelectedFiles) {
        this.sharedSelectedFiles.clear();
        this.sharedSelectedFiles.addAll(sharedSelectedFiles);
        notifySelectedFilesChange();
    }

    /**
     * 状态监听器接口
     */
    public interface StateListener {
        default void onAllListFilesChanged() {
        }

        /**
         * 当已选择文件列表改变时调用
         */
        default void onSelectedFilesChanged() {
        }

        /**
         * 当歌曲数据缓存改变时调用
         */
        default void onSongDataChanged() {
        }

        /**
         * 当计划生成时长改变时调用
         *
         * @param plannedDuration 计划生成时长（分钟）
         */
        default void onPlannedDurationChanged(double plannedDuration) {
        }

        /**
         * 当是否保持原速改变时调用
         *
         * @param keepOriginalSpeed 是否保持原速
         */
        default void onKeepOriginalSpeedChanged(boolean keepOriginalSpeed) {
        }

        /**
         * 当是否截断超出时长的文件改变时调用
         *
         * @param truncateExceedingFiles 是否截断超出时长的文件
         */
        default void onTruncateExceedingFilesChanged(boolean truncateExceedingFiles) {
        }

        /**
         * 当搜索文本改变时调用
         *
         * @param searchText 搜索文本
         */
        default void onSearchTextChanged(String searchText) {
        }

        /**
         * 当分析进度消息改变时调用
         *
         * @param message 分析进度消息
         */
        default void onAnalysisProgressMessageChanged(String message) {
        }

        /**
         * 当分析进度百分比改变时调用
         *
         * @param progress 分析进度百分比
         */
        default void onAnalysisProgressChanged(int progress) {
        }

        /**
         * 当前正在分析的文件改变时调用
         *
         * @param file 当前正在分析的文件
         */
        default void onAnalysisCurrentFileChanged(File file) {
        }

        default void onBpmFileAcquired(File bpmFileAcquired){};
    }
}